import ora from 'ora'
import axios from 'axios'
import { isOpenApi3 } from '@/utils/isOpenApi3'
import { ApiData, GenOptions, ReadApiDocsRes } from '@/tsHelpers'
import { codeGenErrorHandler } from '@/utils/codeGenErrorHandler'
export const B_readApiDocs = async (options: GenOptions) => {
  const startMsg = '读取 api-docs 数据中... \n'
  const errMsg = '读取 api-docs 数据失败 \n'

  const spinner = ora(startMsg).start()

  let apiDatas: Array<ApiData | undefined> = []
  try {
    spinner.info('不要担心, 为了发起https请求到“https://generator.swagger.io”，代码中设置了 process.env.NODE_TLS_REJECT_UNAUTHORIZED = \'0\'')
    const origin = new URL(options.url).origin
    const apiDocUrls: Array<{
      name: string;
      url: string;
    }> = []
    if (options.url.indexOf('swagger-config') > -1) {
      // v3 cloud
      const data = (await axios.get(options.url)).data
      data.urls?.forEach(
        (element: {
          contextPath: string;
          name: string;
          order: number;
          serviceName: string;
          url: string;
        }) => {
          apiDocUrls.push({
            name: element.serviceName ?? element.name,
            url: `${origin}${element.url}`,
          })
        }
      )
    } else if (options.url.indexOf('swagger-resources') > -1) {
      // v2 cloud
      const data = (await axios.get(options.url)).data
      data?.forEach(
        (element: {
          location: string;
          name: string;
          swaggerVersion: string;
          url: string;
        }) => {
          apiDocUrls.push({
            name: element.name,
            url: `${origin}${element.url}`,
          })
        }
      )
    } else if (options.url.indexOf('api-docs') > -1) {
      apiDocUrls.push({
        name: 'generated-api',
        url: options.url,
      })
    }

    // 获取doc数据
    apiDatas = await Promise.all(
      apiDocUrls.map((item) => {
        return new Promise<ApiData | undefined>(async (resolve) => {
          let apiDataOrigin
          try {
            apiDataOrigin = (await axios.get(item.url))?.data
          } catch (error) {
            // todo
          }
          if (!apiDataOrigin || apiDataOrigin.code === 500) {
            spinner.warn(item.name + '：api-doc数据获取失败')
            resolve(undefined)
            return
          }
          const translatedData = codeGenErrorHandler(apiDataOrigin)
          const isOAS3 = isOpenApi3(translatedData)
          const originJson = JSON.stringify(translatedData)
          const name = item.name
          spinner.succeed(item.name + '：api-doc数据获取成功')
          resolve({
            name,
            isOAS3,
            originJson,
          })
        })
      })
    )
  } catch (error) {
    spinner.fail(errMsg)
    apiDatas = []
    throw error
  }
  return {
    ...options,
    apiDatas,
  } as ReadApiDocsRes
}
